#pragma once
#include <d3d9.h>
#include "../Interfaces/IEnvironment.h"
#include "../ScreenMask/ScreenMask.h"
#include "../Shas/Shas/Shas.h"

#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))) 
#define FOURCC_RAWZ ((D3DFORMAT)(MAKEFOURCC('R', 'A', 'W', 'Z'))) 

struct r_DepthTextureType
{
	enum Enumeration
	{
		DepthPeeling,
		RAWZ,
		INTZ
	};
};

class DepthTexture
{
private:
	// Common
	r_DepthTextureType::Enumeration type;
	IDirect3DDevice9* device;
	D3DSURFACE_DESC backBufferDescription;
	IEnvironment& environment;
	IShaderSystem& shaderSystem;

	// Special textures (high end ATI/nVidia cards only)
	IDirect3DTexture9 *texture; 
	IDirect3DSurface9 *depthTextureSurface;

	// DepthPeeling only
	D3DVIEWPORT9 viewPort;
	D3DXMATRIX viewMatrix;
	D3DXMATRIX projMatrix;
	D3DXMATRIX worldMatrix;
	int screenMaskCount;
	IShader* depthRenderShader;
	IShader* blackRenderShader;
	std::vector<ScreenMask*> screenMaskList;
	BatchScreenMask* screenMaskBatch;
	ScreenMask* clearMask;
	LPDIRECT3DTEXTURE9 backBufferTexture;

public:
	DepthTexture(IDirect3DDevice9* device, IEnvironment& environment, IShaderSystem& shaderSystem, const std::string& shaderPath);
	~DepthTexture();

	void BindDepthBuffer();
	void CalculateDepthBufferData();

	IDirect3DTexture9* GetTexture(){ return texture; }
	r_DepthTextureType::Enumeration GetType() { return type; }

protected:
	double CalcZDepth(double ad_PercentageDepth);
	void CopyRenderTarget(IDirect3DTexture9* ar_Texture_, RECT* ar_Rect_);
	void Render(IRenderable* ar_ScreenMask_, IShader* ar_Shader_);
	IShader* LoadShader(const std::string& as_FileName, const std::string& as_Path);
};
